#=
常用的晶格
=#


"""
增加时调用
"""
macro ↻(L, s)
    quote
        local s1 = $(esc(s))
        while s1 > $(esc(L))
            s1 = s1-$(esc(L))
        end
        s1
    end
end


"""
减去时调用
"""
macro ↺(L, s)
    quote
        local s1 = $(esc(s))
        while s1 < 1
            s1 = s1+$(esc(L))
        end
        s1
    end
end




""""""
function bonds_ckb(L, t1, t2)
    #
    bonds = []
    ucmap = zeros(Int, L, L)
    for ux in Base.OneTo(L); for uy in Base.OneTo(L)
        ucmap[ux, uy] = L*(uy-1) + ux
    end; end
    #
    println(ucmap)
    #
    for ux in Base.OneTo(L); for uy in Base.OneTo(L)
        Aidx = ucmap[ux, uy]
        #+x
        Bidx = ucmap[@↻(L, ux+1), uy]
        push!(bonds, (Aidx, Bidx, t1))
        #+y
        Bidx = ucmap[ux, @↻(L, uy+1)]
        push!(bonds, (Aidx, Bidx, t1))
        #
        #如果ux+uy是奇数，+x+y, 如果A是偶数，+x-y
        if mod(ux+uy, 2) == 1
            Bidx = ucmap[@↻(L, ux+1), @↻(L, uy+1)]
        else
            Bidx = ucmap[@↻(L, ux+1), @↺(L, uy-1)]
        end
        push!(bonds, (Aidx, Bidx, t2))
    end; end
    return bonds
end



""""""
function ppbonds_ckb(L, abonds, bbonds)
    #
    bonds = []
    ucmap = zeros(Int, L, L)
    for ux in Base.OneTo(L); for uy in Base.OneTo(L)
        ucmap[ux, uy] = L*(uy-1) + ux
    end; end
    #
    println(ucmap)
    #
    for ux in Base.OneTo(L); for uy in Base.OneTo(L)
        Aidx = ucmap[ux, uy]
        nowbd = mod(ux+uy, 2) == 1 ? abonds : bbonds
        #+x
        Bidx = ucmap[@↻(L, ux+1), uy]
        push!(bonds, (Aidx, :up, Bidx, :dn, nowbd["+x"]))
        push!(bonds, (Aidx, :dn, Bidx, :up, -nowbd["+x"]))
        #+y
        Bidx = ucmap[ux, @↻(L, uy+1)]
        push!(bonds, (Aidx, :up, Bidx, :dn, nowbd["+y"]))
        push!(bonds, (Aidx, :dn, Bidx, :up, -nowbd["+y"]))
        #-x
        Bidx = ucmap[@↺(L, ux-1), uy]
        push!(bonds, (Aidx, :up, Bidx, :dn, nowbd["-x"]))
        push!(bonds, (Aidx, :dn, Bidx, :up, -nowbd["-x"]))
        #-y
        Bidx = ucmap[ux, @↺(L, uy-1)]
        push!(bonds, (Aidx, :up, Bidx, :dn, nowbd["-y"]))
        push!(bonds, (Aidx, :dn, Bidx, :up, -nowbd["-y"]))
        #
        #如果ux+uy是奇数，+x+y, 如果A是偶数，+x-y
        if mod(ux+uy, 2) == 1
            Bidx = ucmap[@↻(L, ux+1), @↻(L, uy+1)]
            push!(bonds, (Aidx, :up, Bidx, :dn, abonds["+x+y"]))
            push!(bonds, (Aidx, :dn, Bidx, :up, -abonds["+x+y"]))
            #
            Bidx = ucmap[@↺(L, ux-1), @↺(L, uy-1)]
            push!(bonds, (Aidx, :up, Bidx, :dn, abonds["-x-y"]))
            push!(bonds, (Aidx, :dn, Bidx, :up, -abonds["-x-y"]))
        else
            Bidx = ucmap[@↻(L, ux+1), @↺(L, uy-1)]
            push!(bonds, (Aidx, :up, Bidx, :dn, bbonds["+x-y"]))
            push!(bonds, (Aidx, :dn, Bidx, :up, -bbonds["+x-y"]))
            #
            Bidx = ucmap[@↺(L, ux-1), @↻(L, uy+1)]
            push!(bonds, (Aidx, :up, Bidx, :dn, bbonds["-x+y"]))
            push!(bonds, (Aidx, :dn, Bidx, :up, -bbonds["-x+y"]))
        end
    end; end
    return bonds
end



"""
orders应该包含所有的
corr = O^+ O
O = sum bnd5 bnd_1,2 bnd_3,4
应该自己实现单态或者3态
"""
function ppbuild_from_order_param(orders, refsites)
    bnum = length(orders)
    corrs = []
    for b1 in Base.OneTo(bnum)
        if !(orders[b1][1] in refsites)
            break
        end
        for b2 in Base.OneTo(bnum)
            push!(corrs, (
                orders[b1][3], orders[b1][4],
                orders[b1][1], orders[b1][2],
                orders[b2][1], orders[b2][2],
                orders[b2][3], orders[b2][4],
                adjoint(orders[b1][5])*orders[b2][5]
            ))
        end
    end
    return corrs
end


"""
计算非关联部分
"""
function uncorr_from_ppbuild(corrs, gfc)
    res = 0.0
    for crr in corrs
        if crr[2] == crr[6]
            sgn = -1.0
            res += sgn * crr[9] * gfc[crr[1], crr[5]] * gfc[crr[3], crr[7]]
        else
            sgn = 1.0
            res += sgn * crr[9] * gfc[crr[1], crr[7]] * gfc[crr[3], crr[5]]
        end
        #println("$(crr) $(sgn) $(gfc[1, 7])")
    end
    return res
end

